package com.zg.datapush.metrics;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;

/**
 * 数据推送性能指标收集
 * @author zg
 */
@Component
@RequiredArgsConstructor
@Slf4j
@ConditionalOnClass(MeterRegistry.class)
public class DataPushMetrics {

    private final MeterRegistry meterRegistry;

    /**
     * 记录推送任务执行时间
     */
    public void recordPushExecutionTime(String taskName, String targetType, String status, long durationMs) {
        try {
            Timer.builder("datapush.execution.time")
                    .tag("task", taskName)
                    .tag("targetType", targetType)
                    .tag("status", status)
                    .description("数据推送任务执行时间")
                    .register(meterRegistry)
                    .record(durationMs, java.util.concurrent.TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.warn("记录推送执行时间指标失败", e);
        }
    }

    /**
     * 记录推送数据量
     */
    public void recordPushDataCount(String taskName, String targetType, String status, long count) {
        try {
            Counter.builder("datapush.data.count")
                    .tag("task", taskName)
                    .tag("targetType", targetType)
                    .tag("status", status)
                    .description("数据推送数据量")
                    .register(meterRegistry)
                    .increment(count);
        } catch (Exception e) {
            log.warn("记录推送数据量指标失败", e);
        }
    }

    /**
     * 记录推送任务执行次数
     */
    public void recordPushTaskExecution(String taskName, String targetType, String triggerType, String status) {
        try {
            Counter.builder("datapush.task.execution")
                    .tag("task", taskName)
                    .tag("targetType", targetType)
                    .tag("triggerType", triggerType)
                    .tag("status", status)
                    .description("数据推送任务执行次数")
                    .register(meterRegistry)
                    .increment();
        } catch (Exception e) {
            log.warn("记录推送任务执行次数指标失败", e);
        }
    }

    /**
     * 记录数据源连接时间
     */
    public void recordDataSourceConnectionTime(String datasourceCode, long durationMs) {
        try {
            Timer.builder("datapush.datasource.connection.time")
                    .tag("datasource", datasourceCode)
                    .description("数据源连接时间")
                    .register(meterRegistry)
                    .record(durationMs, java.util.concurrent.TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.warn("记录数据源连接时间指标失败", e);
        }
    }

    /**
     * 记录数据转换时间
     */
    public void recordDataTransformTime(String taskName, long recordCount, long durationMs) {
        try {
            Timer.builder("datapush.data.transform.time")
                    .tag("task", taskName)
                    .tag("recordCount", String.valueOf(recordCount))
                    .description("数据转换时间")
                    .register(meterRegistry)
                    .record(durationMs, java.util.concurrent.TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.warn("记录数据转换时间指标失败", e);
        }
    }

    /**
     * 记录HTTP请求时间（REST推送）
     */
    public void recordHttpRequestTime(String url, String method, int statusCode, long durationMs) {
        try {
            Timer.builder("datapush.http.request.time")
                    .tag("url", url)
                    .tag("method", method)
                    .tag("statusCode", String.valueOf(statusCode))
                    .description("HTTP请求时间")
                    .register(meterRegistry)
                    .record(durationMs, java.util.concurrent.TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.warn("记录HTTP请求时间指标失败", e);
        }
    }

    /**
     * 记录推送错误
     */
    public void recordPushError(String taskName, String targetType, String errorType, String errorMessage) {
        try {
            Counter.builder("datapush.error.count")
                    .tag("task", taskName)
                    .tag("targetType", targetType)
                    .tag("errorType", errorType)
                    .tag("errorMessage", errorMessage.length() > 100 ?
                         errorMessage.substring(0, 100) + "..." : errorMessage)
                    .description("数据推送错误次数")
                    .register(meterRegistry)
                    .increment();
        } catch (Exception e) {
            log.warn("记录推送错误指标失败", e);
        }
    }

    /**
     * 记录任务调度延迟
     */
    public void recordScheduleDelay(String taskName, long delayMs) {
        try {
            Timer.builder("datapush.schedule.delay")
                    .tag("task", taskName)
                    .description("任务调度延迟时间")
                    .register(meterRegistry)
                    .record(delayMs, java.util.concurrent.TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.warn("记录任务调度延迟指标失败", e);
        }
    }

    /**
     * 记录线程池使用情况
     */
    public void recordThreadPoolUsage(String poolName, int activeThreads, int poolSize, int queueSize) {
        try {
            meterRegistry.gauge("datapush.threadpool.active",
                               io.micrometer.core.instrument.Tags.of("pool", poolName), activeThreads);
            meterRegistry.gauge("datapush.threadpool.size",
                               io.micrometer.core.instrument.Tags.of("pool", poolName), poolSize);
            meterRegistry.gauge("datapush.threadpool.queue",
                               io.micrometer.core.instrument.Tags.of("pool", poolName), queueSize);
        } catch (Exception e) {
            log.warn("记录线程池使用情况指标失败", e);
        }
    }
}
